from interpreter import *
from error import *
from type_operate import Value


class RTResult(object):
    """
    value: 多种扩展类型, 如 Number | String | List | Function
    error: 如果发生错误, 该值不为 None
    func_return_value: 如果是函数, 其返回值, Value 对象
    loop_should_continue: 循环 continue
    loop_should_break: 循环 break
    """

    def __init__(self):
        self.value: Value = None
        self.error: RunTimeError = None
        self.func_return_value: Value = None
        self.loop_should_continue = False
        self.loop_should_break = False

    def reset(self):
        """
        重置属性
        :return:
        """
        self.value = None
        self.error = None
        self.func_return_value = None
        self.loop_should_continue = False
        self.loop_should_break = False

    def success(self, value):
        self.reset()
        self.value = value
        return self

    def success_return(self, value):
        self.reset()
        self.func_return_value = value
        return self

    def success_continue(self):
        self.reset()
        self.loop_should_continue = True
        return self

    def success_break(self):
        self.reset()
        self.loop_should_break = True
        return self

    def should_return(self):
        # 其中一个为True，则返回True
        # 即：self.error 存错误，返回True；
        # self.func_return_value函数有返回值返回True
        # self.loop_should_continue跳过此次循环返回True
        # self.loop_should_break 跳出此次循环返回True
        return (
                self.error or
                self.func_return_value or
                self.loop_should_continue or
                self.loop_should_break
        )

    def failure(self, error):
        self.reset()
        self.error = error
        return self

    def register(self, res):
        """
        传递错误给根递归, 并且返回包裹的值
        :param res:
        :return:
        """
        if res.error:
            self.error = res.error
        self.func_return_value = res.func_return_value
        self.loop_should_continue = res.loop_should_continue
        self.loop_should_break = res.loop_should_break
        return res.value


class ParserResult(object):
    """
    node: 语法树解析出的 Node, 如 NumberNode, BinOpNode, UnaryOpNode
    """

    def __init__(self):
        self.error = None
        self.node: Node = None
        self.advance_count = 0  # 占据了多少个 token
        self.last_registered_advance_count = 0  # 上一个解析的非终止符已经前进的距离 如 A => aacBd , a, c, d 都是 1, B 就可能是其他数
        self.to_reverse_count = 0  # 回滚的下标个数

    def success(self, node):
        self.node = node
        return self

    def failure(self, error):
        self.error = error
        return self

    def register_advancement(self):
        self.advance_count += 1
        self.last_registered_advance_count = 1  # 占据一个终止符, +1

    def register(self, res: 'ParserResult'):
        """
        传递错误, 如果抽象语法树上某个节点出错, 可以将错误传递到树根
        :param res:
        :return: 如果是ParserResult,返回node,如果是普通node,直接返回
        """
        if isinstance(res, ParserResult):
            self.last_registered_advance_count = res.advance_count  # 这是一个终止符, 记录一下占据的 token 数目
            self.advance_count += res.advance_count
            if res.error:
                self.error = res.error
            return res.node
        return res

    def try_register(self, parser_result: 'ParserResult'):
        """
        尝试解析当前token, 如果失败了就退回到上一个 token 解析前
        :param parser_result:
        :return:
        """
        if parser_result.error:
            # 失败, 则记录要回退的步数, 回到执行前
            self.to_reverse_count = parser_result.advance_count
            return None
        return self.register(parser_result)
